{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.datasets import load_digits\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# https://zhuanlan.zhihu.com/p/30047153"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 加载数据\n",
    "digits = load_digits()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1797, 64)"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 共1797条数据 64个维度\n",
    "digits.data.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1797,)"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 数据没有标签\n",
    "digits.target.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 切割数据，25%测试，75%训练集\n",
    "from sklearn.model_selection import train_test_split\n",
    "X_train, X_test, y_train, y_test = train_test_split(digits.data, digits.target, test_size=0.25, random_state=33)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.svm import LinearSVC"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 使用SVM模型进行训练并对性能进行评估\n",
    "\n",
    "# 数据标准化\n",
    "ss = StandardScaler()\n",
    "X_dire_train = ss.fit_transform(X_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1347, 64)"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_dire_train.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LinearSVC(max_iter=100000)"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 线性核函数初始化\n",
    "lsvc = LinearSVC(max_iter=100000)\n",
    "# 训练模型\n",
    "lsvc.fit(X_dire_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 预测\n",
    "X_dire_test = ss.transform(X_test) # 对测试集进行同样的标准化处理\n",
    "y_dire_predict = lsvc.predict(X_dire_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The Accuracy of Linear SVC is 0.9511111111111111\n"
     ]
    }
   ],
   "source": [
    "# 使用模型自带的评估函数进行准确性测评 \n",
    "print('The Accuracy of Linear SVC is', lsvc.score(X_dire_test, y_test))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.92      1.00      0.96        35\n",
      "           1       0.95      0.98      0.96        54\n",
      "           2       0.98      1.00      0.99        44\n",
      "           3       0.93      0.93      0.93        46\n",
      "           4       0.97      1.00      0.99        35\n",
      "           5       0.94      0.94      0.94        48\n",
      "           6       0.96      0.98      0.97        51\n",
      "           7       0.92      1.00      0.96        35\n",
      "           8       0.98      0.83      0.90        58\n",
      "           9       0.95      0.91      0.93        44\n",
      "\n",
      "    accuracy                           0.95       450\n",
      "   macro avg       0.95      0.96      0.95       450\n",
      "weighted avg       0.95      0.95      0.95       450\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# 导入classification_report模块对预测结果做更加详细的分析\n",
    "from sklearn.metrics import classification_report\n",
    "print(classification_report(y_test, y_dire_predict, target_names=digits.target_names.astype(str)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.decomposition import PCA\n",
    "estimator = PCA(n_components=20)   # 初始化，64维压缩至20维\n",
    "# 利用训练特征决定（fit）20个正交维度的方向，并转化（transform）原训练特征\n",
    "pca_X_train = estimator.fit_transform(X_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1347, 20)"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 维度从64变为20\n",
    "pca_X_train.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 测试特征也按照上述的20个正交维度方向进行转化（transform）\n",
    "pca_X_test = estimator.transform(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [],
   "source": [
    "pca_svc = LinearSVC(max_iter=100000)\n",
    "pca_svc.fit(pca_X_train, y_train)  # 训练模型 \n",
    "y_predict = pca_svc.predict(pca_X_test) # 进行预测"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The Accuracy of Linear SVC after PCA is 0.9422222222222222\n"
     ]
    }
   ],
   "source": [
    "# 自带评价函数\n",
    "print('The Accuracy of Linear SVC after PCA is', pca_svc.score(pca_X_test,y_test))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.94      0.97      0.96        35\n",
      "           1       0.91      0.96      0.94        54\n",
      "           2       1.00      1.00      1.00        44\n",
      "           3       0.93      0.87      0.90        46\n",
      "           4       1.00      0.94      0.97        35\n",
      "           5       0.90      0.92      0.91        48\n",
      "           6       0.96      0.98      0.97        51\n",
      "           7       0.95      1.00      0.97        35\n",
      "           8       0.91      0.90      0.90        58\n",
      "           9       0.95      0.91      0.93        44\n",
      "\n",
      "    accuracy                           0.94       450\n",
      "   macro avg       0.95      0.94      0.94       450\n",
      "weighted avg       0.94      0.94      0.94       450\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# 详细评价精确率，回调率，f1指数\n",
    "print(classification_report(y_test, y_predict, target_names=np.arange(10).astype(str)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 总结\n",
    "# 相比于将样本数据不降维处理直接拿来训练，PCA降维处理后数据的会损失一点预测准确性(约0.02)，\n",
    "# 因为在降维过程中，尽管规避掉了大量的特征冗余和噪声，但是也会损失一些有用的模式信息，\n",
    "# 但是维度的大大压缩不仅节省了大量模型训练时间，也降低了模型的训练难度，对于高维样本来说是划算的选择。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
